package com.wdd.myplatform.controller;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.wdd.myplatform.entity.BizDevice;
import com.wdd.myplatform.utils.QrUtils;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 压缩文件到压缩包中
 * Created by Administrator on 2021/12/16.
 */
@RequestMapping("/zipDemoController")
@RestController
@Slf4j
public class ZipDemoController {

//    @Value("${qrcode.url}")
    //扫码跳转的url
    private String qrCodeUrl = "www.baidu.com";

    /**
     * 亲测好用
     * 功能:压缩多个文件，输出压缩后的zip文件流
     * @param srcfile：源文件列表
     * @param zipFileName：压缩后的文件名
     * @return
     */
    @GetMapping(value = "/downzip1")
    public ResponseEntity<byte[]> zipFiles(String zipFileName) {
        String base64Test1 = QrCodeUtil.generateAsBase64("test1", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String base64Test2 = QrCodeUtil.generateAsBase64("test2", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String base64Test3 = QrCodeUtil.generateAsBase64("test3", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String [] srcfile = new String[]{base64Test1,base64Test2,base64Test3};
        byte[] buf = new byte[1024];
        // 获取输出流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            // ZipOutputStream类：完成文件或文件夹的压缩
            ZipOutputStream out = new ZipOutputStream(bos);
            for (int i = 0; i < srcfile.length; i++) {
                // 此处可用任意其他输入流将FileInputStream取代,outputStream为其他步骤的输出流
                String base64Str = srcfile[i];
                base64Str = StringUtils.replace(base64Str,"data:image/jpg;base64,","");
                BASE64Decoder decode = new BASE64Decoder();
                byte[] b = decode.decodeBuffer(base64Str);
                 ByteArrayInputStream in = new ByteArrayInputStream(b);
//                FileInputStream in = new FileInputStream(srcfile[i]);
                // 给列表中的文件单独命名
                out.putNextEntry(new ZipEntry(UUID.randomUUID().toString()+".jpg"));
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.closeEntry();
                in.close();
            }
            out.close();
            bos.close();
            System.out.println("压缩完成.");
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 设置http响应头
        HttpHeaders header = new HttpHeaders();
        header.add("Content-Disposition", "attachment;filename=" + zipFileName + ".zip");
        return new ResponseEntity<byte[]>(bos.toByteArray(), header, HttpStatus.CREATED);
    }

    /**
     * 功能:压缩多个文件，输出压缩后的zip文件流
     * @param srcfile：源文件列表
     * @param zipFileName：压缩后的文件名
     * @param response: Http响应
     */
    @GetMapping(value = "/downzip")
    public void zipFiles(String zipFileName, HttpServletResponse response) {
//        File[] srcFiles = { new File("E:\\photo\\marriage photos\\横\\259A1302.JPG"), new File("E:\\photo\\marriage photos\\横\\259A1305.JPG"), new File("E:\\photo\\marriage photos\\横\\259A1317.JPG") };

        String base64Test1 = QrCodeUtil.generateAsBase64("test1", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String base64Test2 = QrCodeUtil.generateAsBase64("test2", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String base64Test3 = QrCodeUtil.generateAsBase64("test3", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String [] srcFiles = new String[]{base64Test1,base64Test2,base64Test3};
        byte[] buf = new byte[1024];
        // 获取输出流
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            response.reset(); // 重点突出
            // 不同类型的文件对应不同的MIME类型
            response.setContentType("application/x-msdownload");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + zipFileName + ".zip");

            // ZipOutputStream类：完成文件或文件夹的压缩
            ZipOutputStream out = new ZipOutputStream(bos);
            for (int i = 0; i < srcFiles.length; i++) {
//                FileInputStream in = new FileInputStream(file);
                InputStream in = new FileInputStream(srcFiles[i]);
                // 给列表中的文件单独命名
                out.putNextEntry(new ZipEntry(UUID.randomUUID().toString()));
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.closeEntry();
                in.close();
            }
            out.close();
            bos.close();
            System.out.println("压缩完成.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private File transferToFile(MultipartFile multipartFile) {
//        选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
        File file = null;
        try {
            String originalFilename = multipartFile.getOriginalFilename();
            String[] filename = originalFilename.split(".");
            file=File.createTempFile(filename[0], filename[1]);
            multipartFile.transferTo(file);
            file.deleteOnExit();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    public static void main(String[] args) {
        File[] srcFiles = { new File("E:\\photo\\marriage photos\\横\\259A1302.JPG"), new File("E:\\photo\\marriage photos\\横\\259A1305.JPG"), new File("E:\\photo\\marriage photos\\横\\259A1317.JPG") };
        File zipFile = new File("E:\\ZipFile.zip");
        // 调用压缩方法
        zipFiles(srcFiles, zipFile);
    }
    public static void zipFiles(File[] srcFiles, File zipFile) {
        // 判断压缩后的文件存在不，不存在则创建
        if (!zipFile.exists()) {
            try {
                zipFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String base64Test1 = QrCodeUtil.generateAsBase64("test1", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String base64Test2 = QrCodeUtil.generateAsBase64("test2", new QrConfig().setHeight(200).setWidth(200), "jpg");
        String base64Test3 = QrCodeUtil.generateAsBase64("test3", new QrConfig().setHeight(200).setWidth(200), "jpg");
        // 创建 FileOutputStream 对象
        FileOutputStream fileOutputStream = null;
        // 创建 ZipOutputStream
        ZipOutputStream zipOutputStream = null;
        // 创建 FileInputStream 对象
        FileInputStream fileInputStream = null;

        try {
            // 实例化 FileOutputStream 对象
            fileOutputStream = new FileOutputStream(zipFile);
            // 实例化 ZipOutputStream 对象
            zipOutputStream = new ZipOutputStream(fileOutputStream);
            // 创建 ZipEntry 对象
            ZipEntry zipEntry = null;
            // 遍历源文件数组
            for (int i = 0; i < srcFiles.length; i++) {
                // 将源文件数组中的当前文件读入 FileInputStream 流中
                fileInputStream = new FileInputStream(srcFiles[i]);
                // 实例化 ZipEntry 对象，源文件数组中的当前文件
                zipEntry = new ZipEntry(srcFiles[i].getName());
                zipOutputStream.putNextEntry(zipEntry);
                // 该变量记录每次真正读的字节个数
                int len;
                // 定义每次读取的字节数组
                byte[] buffer = new byte[1024];
                while ((len = fileInputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, len);
                }
            }
            zipOutputStream.closeEntry();
            zipOutputStream.close();
            fileInputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static InputStream BaseToInputStream(String base64string){
        ByteArrayInputStream stream = null;
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes1 = decoder.decodeBuffer(base64string);
            stream = new ByteArrayInputStream(bytes1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stream;
    }

    /**
     * 下载设备二维码,将二维码嵌入图片中并添加文字，多个二维码图片以压缩文件形式浏览器下载
     *
     * @return
     */
    @GetMapping("/downLoadDeviceQrCode")
    public ResponseEntity<byte[]> downLoadDeviceQrCode(@ApiParam(name="ids(以逗号分隔)",required=true)@RequestParam(name="ids",required=true) String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
//        List<BizDeviceModel> bizDeviceList = deviceService.listDeviceByIds(idList);
        // TODO: 2021/12/27  从数据库中查询出数据，改为自己的业务代码
        List<BizDevice> bizDeviceList = new ArrayList<>();
        BizDevice bizDevice = new BizDevice();
        bizDevice.setAreaName("圣地亚哥");
        bizDevice.setDeviceSn("ho");
        bizDeviceList.add(bizDevice);
        byte[] buf = new byte[1024];
        // 获取输出流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        // ZipOutputStream类：完成文件或文件夹的压缩
        ZipOutputStream out = new ZipOutputStream(bos);
        try{
            for (BizDevice bizDeviceModel:bizDeviceList){
                String qrCode = bizDeviceModel.getQrCode();
                //如果设备二维码为空，则先生成二维码后下载
                if(StringUtils.isBlank(qrCode)){
                    StringBuffer stringBuffer = new StringBuffer();
                    stringBuffer.append(qrCodeUrl).append("?deviceSn=").append(bizDeviceModel.getDeviceSn());
                    stringBuffer.append("&_t=").append(System.currentTimeMillis());
                    QrConfig qrConfig = new QrConfig();
                    qrConfig.setWidth(200);
                    qrConfig.setHeight(200);
                    //生成二维码
                    BufferedImage image = QrCodeUtil.generate(stringBuffer.toString(), QrUtils.getWIDTH(), QrUtils.getHEIGHT());
                    //将二维码图片嵌入大图中，并添加文字
                    qrCode = QrUtils.combineCodeAndPicToBase64(image, StringUtils.trimToEmpty(bizDeviceModel.getAreaName()) + StringUtils.trimToEmpty(bizDeviceModel.getDeviceSn()));
                }
                BASE64Decoder decode = new BASE64Decoder();
                //不加这一步会导致生成的图片无法查看
                qrCode = StringUtils.replace(qrCode,"data:image/jpg;base64,","");
                byte[] b = decode.decodeBuffer(qrCode);
                ByteArrayInputStream in = new ByteArrayInputStream(b);
                // 给列表中的文件单独命名
                out.putNextEntry(new ZipEntry("二维码名称.jpg"));
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.closeEntry();
                in.close();
            }
            out.close();
            bos.close();
        }catch (IOException e) {
            log.error("下载失败",e);
        }
        log.info("压缩完成");
        // 设置http响应头
        HttpHeaders header = new HttpHeaders();
        header.add("Content-Disposition", "attachment;filename=qrcode.zip");
        return new ResponseEntity<byte[]>(bos.toByteArray(), header, HttpStatus.CREATED);
    }

}
